////////////////////////////////////////////////////////////////////////////////
//
//  FLYING KIWI BV
//  Copyright 2010 Flying Kiwi BV
//  All Rights Reserved.
//
//  NOTICE: Flying Kiwi permits you to use, modify, and distribute this file
//  in accordance with the terms of the license agreement accompanying it.
//
////////////////////////////////////////////////////////////////////////////////
package plantool.settings {
	//--------------------------------------------------------------------------
	//  Imports
	//--------------------------------------------------------------------------
	import flash.events.Event;
	
	import kiwi.utils.Validation;
	
	import plantool.core.CoreDispatcher;
	import plantool.data.Field;
	import plantool.data.FieldTypes;
	import plantool.data.QueryErrorResult;
	import plantool.data.QueryResult;
	import plantool.data.Table;
	
	//--------------------------------------------------------------------------
	//  [Metadata (Events, Style, Effects etc)]
	//--------------------------------------------------------------------------
	[Event(name="complete", type="flash.events.Event")]
	
	//--------------------------------------------------------------------------
	//  Class declaration
	//--------------------------------------------------------------------------
	public dynamic final class Settings extends CoreDispatcher {
		//--------------------------------------------------------------------------
		//Class constants
		//--------------------------------------------------------------------------
		public static const TYPE_STRING:String		= "String";
		public static const TYPE_INT:String			= "Int";
		
		public static const SETTING_GLOBAL_MARGIN:String	= "global_margin";
		public static const SETTING_HOURS_PER_DAY:String	= "users_hours_per_day";
		public static const SETTING_START_HOUR:String		= "users_start_hour";
		public static const SETTING_WEEK_STARTS_ON:String 	= "week_starts_on";
		public static const SETTING_DAYS_PER_WEEK:String 	= "days_per_week";
		public static const SETTING_SHOW_SATERDAY:String	= "show_saterday";
		public static const SETTING_SHOW_SUNDAY:String		= "show_sunday";
		
		//--------------------------------------------------------------------------
		//Class variables
		//--------------------------------------------------------------------------
		private static var _instance:Settings		= null;
		private var _settings:Array					= new Array();
		
		//--------------------------------------------------------------------------
		//Class properties
		//--------------------------------------------------------------------------
		
		//--------------------------------------------------------------------------
		//Constructor and Destructor
		//--------------------------------------------------------------------------
		public function Settings(pvt:PrivateConstructorClass) {
			super();
		}
		
		//--------------------------------------------------------------------------
		//Class methods
		//--------------------------------------------------------------------------
		public static function getInstance():Settings {
			//check if instance exists, if not create one
			if (!Validation.isSet(_instance)) {
				_instance = new Settings(new PrivateConstructorClass());
			}
			
			//return instance
			return _instance;
		}
		
		private function onComplete_createSettingsStructure():void {
			//init default settigns
			var globalMargin:Setting 	= new Setting();
			globalMargin.setting_id		= SETTING_GLOBAL_MARGIN;
			globalMargin.value			= "20";
			globalMargin.type			= Settings.TYPE_INT;
			initSetting(globalMargin);
			
			//load all settings
			//try to get the setting from the database and return it to the caller
			databaseManager.query("SELECT * FROM `settings`", onComplete_getSettings, onError_getSettings, Setting);
		}
		
		private function onComplete_getSettings(result:QueryResult):void {
			//validate settings
			if (Validation.isSet(result.data)) {
				//store all settings
				for (var i:uint = 0; i < result.data.length; i++) {
					//check for valid setting
					var setting:Setting = result.data[i] as Setting;
					if (Validation.isSet(setting) && Validation.isSet(setting.setting_id)) {
						_settings[setting.setting_id] = setting;
					}
				}
			}
			
			//inform listeners
			dispatchEvent(new Event(Event.COMPLETE));
		}
		
		private function onError_getSettings(result:QueryErrorResult):void {
			trace("Error retrieving settings");
		}
		
		protected override function init():void {
			//set status
			statusManager.status = "Checking settings...";
			
			//create table structure
			var table:Table = new Table("settings");
			table.addField(new Field("setting_id"	, FieldTypes.VARCHAR));
			table.addField(new Field("type"			, FieldTypes.VARCHAR));
			table.addField(new Field("value"		, FieldTypes.VARCHAR));
			
			//create table
			databaseManager.createTable(table, onComplete_createSettingsStructure);
		}
		
		public function initSetting(setting:Setting):void {
			//check if setting doesnt exist
			if (Validation.isSet(setting.setting_id) && !Validation.isSet(_settings[setting.setting_id])) {
				_settings[setting.setting_id] = setting;
			} else {
				trace("Setting", setting.setting_id, "already exists, override setting with setSetting");
			}
		}
		
		public function getSetting(setting_id:String):Setting {
			//check if setting exists
			if (Validation.isSet(setting_id) && Validation.isSet(_settings[setting_id])) {
				return _settings[setting_id];
			}
			throw new Error("Error getting setting. init all settings you want to use with initSetting(setting:Setting);");
			return null;
		}
	}
}

//--------------------------------------------------------------------------
//END OF PACKAGE
//Define the PrivateConstructorClass here so an instance cannot be by anyone
//except for the class defined in the above package
//--------------------------------------------------------------------------
class PrivateConstructorClass {
	//--------------------------------------------------------------------------
	//Constructor and Destructor
	//--------------------------------------------------------------------------
	public function PrivateConstructorClass() {
	}
}